1

# Real-time Web Communications

## OSCON - Portland, OR

### http://spoutserver.com/talks/realtime.html

Scott Mattocks | @scottmattocks | scott@crisscott.com

Thanks http://html5rocks.com

## Old Web

- Lots of data
- One-way communication
- User asks for everything

## New Web

- Information as it happens
- Data flowing in both directions

## Timeliness

There shall be no delay in presenting the user with their information.

## Efficency

There shall be no wasted bytes.

- X bytes sent for request (GET headers)
- Y bytes sent for response (body and headers)
- Z bytes of new data

- Z / (X + Y) = efficiency

## Efficency

Remeber these for later…

- GET headers = 410 bytes
- Response headers = 210 bytes
- New data = 100 bytes

## Scalability

The experience for the first 20 users shall be the same as it is for the first 20,000.

Not Good

- Short Polling
- Long Polling
- Long Polling with 2 servers
- WebSockets

    function poll_server() {
        new Ajax.Request(this.urlPolling, {
               method:      'post',
               parameters:  data,
               onSuccess:   this.successHandler,
               onFailure:   this.handleFailure,
               onException: this.handleException
            });
    }

    setInterval('poll_server()', 5000);

Arrrgh! Find me some treasure!
Avast! There be no treasure!

- Nothing can happen until ths ship gets back
- The faster you poll, the closer you get to real time
- The faster you poll, the less efficient you are
- Requires 1 HTTP connection and 1 database connection each time you check for more data

This is not realtime communication.

## Where did we go wrong?

- Extremely innefficient: If 1 in 10 calls yeilds a new message, 1.5% of the data is new message content
- There are black out periods between and during server calls
- Uses too many resources

Your sysadmin

    function poll_server() {
        new Ajax.Request(this.urlPolling, {
               method:      'post',
               parameters:  data,
               onSuccess:   this.successHandler,
               onFailure:   this.handleFailure,
               onException: this.handleException
            });
    }
    function successHandler(data) {
        // Do something with the data
        this.poll_server();
    }

How do you know when there is new data?

    while (true) {
        $data = $db->query($query);
        if ($data) {
            break;
        }
    }

If this looks like a good idea to you, please leave now.

Arrrgh! Find me some treasure!
Aye Cap'n, we found some loot!
Ahoy!

- Nothing can happen until ths ship gets back
- You send and receive headers along with the data
- Requires 1 HTTP connection and 1 database connection each time you check for more data

This is not realtime communication.

## Where did we go wrong?

- Slightly more efficient: 13.8% of the data is new message content
- There are black out periods between server calls
- Polling on the server is no better than polling on the client

Your sysadmin

We need a way to know when there are updates without polling the database

We can connect to two servers that talk to each other

- One server sends the main page body
- One server sends the new messages
- The main server lets the other server know when a new message arrives

    <?php
    $query = 'INSERT INTO messages VALUES (?, ?)';
    $stmt  = $pdo->prepare($query);
    $stmt->prepare($message, $date);
    $polling_server->send($message);
    ?>

    <?php
    foreach ($this->waiting as $connection) {
        $connection->respond($message);
    }
    ?>

## Where did we go wrong?

- Efficiency is the same
- We still have black outs
- But, the sysadmin isn't as angry

A 2011 Ford AJAX 150

> The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers that does not rely on opening multiple HTTP connections (e.g. using XMLHttpRequest or <iframe>s and long polling). - WebSocket Protocol

WebSockets == Long Polling
(but cooler)
Arrrgh! Find me some treasure!
Aye Cap'n, we found some loot!
Ahoy!

- After one handshake the money just keeps coming
- The only thing sent back is treasure (no headers)
- The connection is always open

This is realtime communication.

## Where did we go wrong?

- Efficiency is 100%: Every byte sent and recieved is meaningful
- No black outs
- The sysadmin and the customer are happy

Hint: We didn't go wrong

    var ws = new WebSocket(url);
    ws.onopen = function() {
         // Called when the connection opens
         };
    ws.onmessage = function() {
         // Called when the server sends stuff
         };
    ws.onclose = function() {
        // Called when the connection is killed
        };
    ws.send('Some awesome data');
    // Some time later...
    ws.close();

    GET /demo HTTP/1.1
    Host: example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: AQIDBAUGBwgJCgsMDQ4PEC==
    Sec-WebSocket-Origin: http://example.com
    Sec-WebSocket-Version: 7

    HTTP/1.1 101 Switching Protocols
    Upgrade: WebSocket
    Connection: Upgrade
    Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=

Questions?

http://spoutserver.com
http://dev.w3.org/html5/websockets/
http://www.whatwg.org/specs/web-socket-protocol/